#include "../../../Include/DataType/Graph/WizDataTypeGraph.hpp"
#include "../../../Include/DataType/Graph/WizDataTypeGraphNode.hpp"
#include "../../../Include/DataType/Graph/WizDataTypeGraphLink.hpp"

namespace Wiz
{
    namespace DGraph
    {
        namespace Node
        {
            ////////////////////////////////////////////////////////////////////
            ////////////////////////////////////////////////////////////////////
            Type::~Type()
            {
                this->Clear();
            }

            ::Wiz::DGraph::Link::Input::Ptr Type::CreateInputLink()
            {
                return new ::Wiz::DGraph::Link::Input::Type();
            }
            ::Wiz::DGraph::Link::Output::Ptr Type::CreateOutputLink()
            {
                return new ::Wiz::DGraph::Link::Output::Type();
            }

            ::Wiz::Void::Type Type::DestroyLink(::Wiz::DGraph::Link::Input::Ptr LinkPtr)
            {
                delete LinkPtr;
            }
            ::Wiz::Void::Type Type::DestroyLink(::Wiz::DGraph::Link::Output::Ptr LinkPtr)
            {
                delete LinkPtr;
            }

            ::Wiz::Void::Type Type::Clear()
            {
                ::Wiz::DGraph::Link::Input::Set::Iterator   ICurr;
                ::Wiz::DGraph::Link::Input::Set::ForEach    IFE(ICurr, this->m_Input);
                while (IFE.HasMoreElement())
                {
                    (*ICurr)->Clear();

                    this->DestroyLink(*ICurr);
                }
                this->m_Input.Clear();

                ::Wiz::DGraph::Link::Output::Set::Iterator   OCurr;
                ::Wiz::DGraph::Link::Output::Set::ForEach    OFE(OCurr, this->m_Output);
                while (OFE.HasMoreElement())
                {
                    (*OCurr)->Clear();

                    this->DestroyLink(*OCurr);
                }
                this->m_Output.Clear();
            }

            ::Wiz::Void::Type Type::InsertInputLink(::Wiz::DGraph::Link::Input::Ptr InPtr)
            {
                this->m_Input.Insert(InPtr);
                InPtr->SetOwner(this);
            }

            ::Wiz::Void::Type Type::InsertOutputLink(::Wiz::DGraph::Link::Output::Ptr OutPtr)
            {
                this->m_Output.Insert(OutPtr);
                OutPtr->SetOwner(this);
            }
            ////////////////////////////////////////////////////////////////////
            ////////////////////////////////////////////////////////////////////
        } /// end of namespace Node
    } /// end of namespace DGraph

    //////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////

    namespace UGraph
    {
        namespace Node
        {
            Type::~Type()
            {
                this->Clear();
            }
            ::Wiz::Void::Type Type::Break(::Wiz::UGraph::Node::Ptr NodePtr)
            {
                ::Wiz::UGraph::Node::Set::Iterator Itr = this->m_Connected.Find(NodePtr);
                if (Itr != this->m_Connected.End())
                {
                    this->m_Connected.Erase(Itr);
                }

                Itr = NodePtr->m_Connected.Find(this);
                if (Itr != NodePtr->m_Connected.End())
                {
                    NodePtr->m_Connected.Erase(Itr);
                }
            }
            ::Wiz::Void::Type Type::Clear()
            {
                ::Wiz::UGraph::Node::Set::ConstIterator Curr;
                ::Wiz::UGraph::Node::Set::ConstForEach  FE(Curr, this->m_Connected);
                while (FE.HasMoreElement())
                {
                    ::Wiz::UGraph::Node::Set::Iterator Itr = (*Curr)->m_Connected.Find(this);
                    if (Itr != (*Curr)->m_Connected.End())
                    {
                        (*Curr)->m_Connected.Erase(Itr);
                    }
                }

                this->m_Connected.Clear();
            }
            ::Wiz::Void::Type Type::Connect(::Wiz::UGraph::Node::Ptr NodePtr)
            {
                WIZ_ASSERT(NodePtr != WIZ_NULL);
                this->m_Connected.Insert(NodePtr);
                NodePtr->m_Connected.Insert(this);
            }
        } /// end of namespace Node
    } /// end of namespace UGraph
} /// end of namespace Wiz
